package com.dmz.insclient.client;

import java.text.DecimalFormat;

import com.dmz.insclient.utils.AppValues;
import com.dmz.insclient.utils.ConnectParam;
import com.dmz.insclient.utils.EnvConfig;
import com.dmz.insclient.utils.XmlUtils;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;


/**
 * @author lee
 */
@Slf4j
public class TcpClient {

    // 发送报文至CSP
    public String sendToCsp(String dateStr, String tranType) throws Exception {
        /**
         * 本方法执行内容以及步骤
         *
         * @kuroneko1 创建Scoket链接
         * @kuroneko2 组装要发送的报文
         * @kuroneko3 发送报文，并获取返回的报文信息
         */

        /* @kuroneko1 */
        ConnectParam param = showSocketParamCsp();
        ISocketLog iSocketLog = new SocketLog();
        ISocketClient client = new SocketClientNew();
        /* @kuroneko2 */

        // 获取请求报文流
        String message = dateStr;

        /* 发送报文到CSP并接收返回信息 */

        // 报文：4位的字符串长度+请求报文内容
        String messageToCSP = new DecimalFormat("0000").format((message).getBytes("GBK").length) + message;

        log.info("发送至CSP的报文为：{}", messageToCSP);

        // 发送CSP，并接收CSP返回报文result1
        String retMsg = client.sendToCsp(messageToCSP, param, iSocketLog);
        log.info("收到CSP的返回报文为：{}", retMsg);

        // 此处增加返回报文的判断逻辑，如果为空或者长度小于8，则不进行截取
        if (!"".equals(retMsg) && retMsg.length() > 8) {
            return retMsg;
        } else {
            log.error("CSP返回报文内容有错，长度小于8或者为空:{}", retMsg);
            return "9999|与CSP通信失败";
        }

    }

    /**
     * 获取Socket配置-Csp
     *
     * @return
     */
    public ConnectParam showSocketParamCsp() {
        ConnectParam param = new ConnectParam();
        param.setName("养老保险代发报文发送至csp");
        param.setIp(EnvConfig.getProperty("skt.server.ip"));
        param.setPort(Integer.parseInt(EnvConfig.getProperty("skt.server.port")));
        param.setClientTryTimes(Integer.parseInt(EnvConfig.getProperty("client.try.times")));
        return param;
    }

    //发送报文至Bps
    public String sendToBps(String dateStr, String tranType) throws Exception {
        /**
         * 本方法执行内容以及步骤
         *
         * @kuroneko1 创建Scoket链接
         * @kuroneko2 组装要发送的报文
         * @kuroneko3 发送报文，并获取返回的报文信息
         */

        /* @kuroneko1 */
        ConnectParam param = showSocketParamBps();
        ISocketLog iSocketLog = new SocketLog();
        ISocketClient client = new SocketClientNew();
        /* @kuroneko2 */

        // 获取请求报文流
        String message = dateStr;

        /* 发送报文到Bps并接收返回信息 */
        String messageToBps = null;
        messageToBps = tranType + message;
        log.info("发送至BPS的报文为：{}", messageToBps);

        // 发送Bps，并接收Bps返回报文result1
        String result1 = client.sendToBps(messageToBps, param, iSocketLog);
        log.info("收到BPS的返回报文为：{}", result1);

        // 此处增加返回报文的判断逻辑，如果为空或者长度小于4，则不进行截取
        if (!"".equals(result1) && result1.length() > 4) {
            log.info("对方返回码：{}", result1.split("\\|", -1)[0]);
            log.info("对方返回信息：{}", result1.split("\\|", -1)[1]);
            return result1;
        } else {
            log.error("BPS返回报文内容有错，长度小于8或者为空{}", result1);
            return "null|与BPS系统通信失败";
        }
    }

    /**
     * 获取Socket配置-Bps
     *
     * @return
     */
    public ConnectParam showSocketParamBps() {
        ConnectParam param = new ConnectParam();
        param.setName("养老保险代发报文发送至bps");
        param.setIp(EnvConfig.getProperty("bps.server.ip"));
        param.setPort(Integer.parseInt(EnvConfig.getProperty("bps.server.port")));
        param.setClientTryTimes(Integer.parseInt(EnvConfig.getProperty("client.try.times")));
        return param;
    }

    /**
     * 获取Socket配置-Bps
     *
     * @return
     */
    public ConnectParam showSocketParamsb() {
        ConnectParam param = new ConnectParam();
        param.setName("养老保险代发报文发送至sb");
        param.setIp(EnvConfig.getProperty("sb.server.ip"));
        param.setPort(Integer.parseInt(EnvConfig.getProperty("sb.server.port")));
        param.setClientTryTimes(Integer.parseInt(EnvConfig.getProperty("client.try.times")));
        return param;
    }


    /**
     * 为田川特别写的发送中银E贷社保报文 处理了换行空格回车
     *
     * @param doc
     * @param overSign
     * @return
     * @throws Exception
     */
    public String sendToSbE(Document doc, String overSign) throws Exception {
        /**
         * 本方法执行内容以及步骤
         *
         * @kuroneko1 创建Scoket链接
         * @kuroneko2 组装要发送的报文
         * @kuroneko3 发送报文，并获取返回的报文信息
         */

        /* @kuroneko1 */
        ConnectParam param = showSocketParamsb();
        ISocketLog iSocketLog = new SocketLog();
        ISocketClient client = new SocketClientNew();
        /* @kuroneko2 */

        // 获取请求报文流
        String message = XmlUtils.docToXml(doc);

        /* 发送报文到社保并接收返回信息 */

        // 报文：4位的字符串长度+请求报文内容
        // String messageToCSP=new
        // DecimalFormat("0000").format(message.getBytes("GBK").length+6)+"YLBXOK"+message;
        message = XmlUtils.replaceBlank(message);
        String messageToCSP = message + overSign;
        log.info("发送至社保的报文为：{}", messageToCSP);
        // 发送社保，并接收社保返回报文result1
        String result1 = client.sendToSb(messageToCSP, param, iSocketLog);
        String result2 = "";
        log.info("收到社保的返回报文为：{}", result1);

        if ("".equals(result1.trim())) {
            log.info("社保返回报文内容有错，长度小于8或者为空{}", result1);

            return "null";
        }
        result1 = result1.substring(result1.indexOf("<"));
        String[] strs = result1.split(">");
        for (int i = 0; i < strs.length - 1; i++) { //什么时候处理了个减一操作
            result2 += strs[i].toString() + ">";
        }
        Document docRecieved = DocumentHelper.parseText(result2.trim());//将xml字符串转成xml

        /* 返回报文到Bps*/
//		String messageToBps=null;
//		messageToBps= overSign + message;
//		LOG.info("返回BPS的报文为：" + messageToBps);

        if (!"".equals(result2) && result2.length() > 8) {
            log.info("对方返回码：{}", docRecieved.getRootElement().element("BusiText").element("Rst").element("Code").getText().toString());
            log.info("对方返回信息：{}", docRecieved.getRootElement().element("BusiText").element("Rst").element("Info").getText().toString());
            return result2;
        } else {
            log.info("社保返回报文内容有错，长度小于8或者为空{}", result1);
            return "null|与社保通信失败";
        }
//		return result1;
    }

    public String sendToSb(Document doc, String overSign) throws Exception {
        /**
         * 本方法执行内容以及步骤
         *
         * @kuroneko1 创建Scoket链接
         * @kuroneko2 组装要发送的报文
         * @kuroneko3 发送报文，并获取返回的报文信息
         */

        /* @kuroneko1 */
        ConnectParam param = showSocketParamsb();
        ISocketLog iSocketLog = new SocketLog();
        ISocketClient client = new SocketClientNew();
        /* @kuroneko2 */

        // 获取请求报文流
        String message = XmlUtils.docToXml(doc);

        /* 发送报文到社保并接收返回信息 */

        // 报文：4位的字符串长度+请求报文内容
        // String messageToCSP=new
        // DecimalFormat("0000").format(message.getBytes("GBK").length+6)+"YLBXOK"+message;
        String messageToCSP = message + overSign;
        log.info("发送至社保的报文为：{}", messageToCSP);
        // 发送社保，并接收社保返回报文result1
        String result1 = client.sendToSb(messageToCSP, param, iSocketLog);
        String result2 = "";
        log.info("收到社保的返回报文为：{}", result1);

        if (result1.trim().equals("")) {
            log.error("社保返回报文内容有错，长度小于8或者为空{}", result1);

            return "null";
        }
        result1 = result1.substring(result1.indexOf("<"));
        String[] strs = result1.split(">");
        for (int i = 0; i < strs.length - 1; i++) { //什么时候处理了个减一操作
            result2 += strs[i].toString() + ">";
        }
        Document docRecieved = DocumentHelper.parseText(result2.trim());//将xml字符串转成xml

        /* 返回报文到Bps*/
//		String messageToBps=null;
//		messageToBps= overSign + message;
//		LOG.info("返回BPS的报文为：" + messageToBps);

        if (!"".equals(result2) && result2.length() > 8) {
            log.info("对方返回码：{}", docRecieved.getRootElement().element("BusiText").element("Rst").element("Code").getText().toString());
            log.info("对方返回信息：{}", docRecieved.getRootElement().element("BusiText").element("Rst").element("Info").getText().toString());
            return result2;
        } else {
            log.info("社保返回报文内容有错，长度小于8或者为空{}", result1);
            return "null|与社保通信失败";
        }
//		return result1;
    }
}
